package com.laundry.service;

import com.laundry.dto.OrderRequest;
import com.laundry.entity.*;
import com.laundry.repository.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class LaundryOrderService {
    
    private final LaundryOrderRepository orderRepository;
    private final UserRepository userRepository;
    private final ServiceRepository serviceRepository;
    private final OrderItemRepository orderItemRepository;
    private final OrderProgressRepository orderProgressRepository;
    
    @Transactional
    public LaundryOrder createOrder(OrderRequest request) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userRepository.findByUsernameOrEmailOrMobile(username, username, username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 创建订单
        LaundryOrder order = new LaundryOrder();
        order.setUser(user);
        order.setCustomerName(request.getCustomerName());
        order.setCustomerPhone(request.getCustomerPhone());
        order.setPickupAddress(request.getPickupAddress());
        order.setDeliveryAddress(request.getDeliveryAddress());
        order.setTotalAmount(request.getTotalAmount());
        order.setFinalAmount(request.getTotalAmount());
        order.setNotes(request.getNotes());
        order.setStatus(LaundryOrder.OrderStatus.PENDING);
        order.setPaymentStatus(LaundryOrder.PaymentStatus.UNPAID);
        
        LaundryOrder savedOrder = orderRepository.save(order);
        
        // 创建订单项
        List<OrderItem> orderItems = new ArrayList<>();
        for (OrderRequest.OrderItemRequest itemRequest : request.getItems()) {
            com.laundry.entity.Service service = serviceRepository.findById(itemRequest.getServiceId())
                    .orElseThrow(() -> new RuntimeException("服务不存在"));
            
            OrderItem orderItem = new OrderItem();
            orderItem.setOrder(savedOrder);
            orderItem.setService(service);
            orderItem.setServiceName(service.getName());
            orderItem.setUnitPrice(service.getPrice());
            orderItem.setQuantity(itemRequest.getQuantity());
            orderItem.setTotalPrice(service.getPrice().multiply(BigDecimal.valueOf(itemRequest.getQuantity())));
            orderItem.setNotes(itemRequest.getNotes());
            
            orderItems.add(orderItem);
        }
        
        orderItemRepository.saveAll(orderItems);
        
        // 创建订单进度记录
        OrderProgress progress = new OrderProgress();
        progress.setOrder(savedOrder);
        progress.setStatus(LaundryOrder.OrderStatus.PENDING);
        progress.setDescription("订单已创建，等待确认");
        progress.setOperator("系统");
        orderProgressRepository.save(progress);
        
        return savedOrder;
    }
    
    public Page<LaundryOrder> getUserOrders(Pageable pageable) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userRepository.findByUsernameOrEmailOrMobile(username, username, username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        return orderRepository.findByUser(user, pageable);
    }
    
    public Page<LaundryOrder> getUserOrdersByStatus(LaundryOrder.OrderStatus status, Pageable pageable) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userRepository.findByUsernameOrEmailOrMobile(username, username, username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        return orderRepository.findByUserAndStatus(user, status, pageable);
    }
    
    public LaundryOrder getOrderById(Long id) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userRepository.findByUsernameOrEmailOrMobile(username, username, username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        LaundryOrder order = orderRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        if (!order.getUser().getId().equals(user.getId())) {
            throw new RuntimeException("无权访问此订单");
        }
        
        return order;
    }
    
    @Transactional
    public LaundryOrder updateOrderStatus(Long id, LaundryOrder.OrderStatus status) {
        LaundryOrder order = getOrderById(id);
        order.setStatus(status);
        
        // 创建进度记录
        OrderProgress progress = new OrderProgress();
        progress.setOrder(order);
        progress.setStatus(status);
        progress.setDescription(getStatusDescription(status));
        progress.setOperator("系统");
        orderProgressRepository.save(progress);
        
        return orderRepository.save(order);
    }
    
    @Transactional
    public LaundryOrder cancelOrder(Long id, String reason) {
        LaundryOrder order = getOrderById(id);
        
        if (order.getStatus() != LaundryOrder.OrderStatus.PENDING && 
            order.getStatus() != LaundryOrder.OrderStatus.CONFIRMED) {
            throw new RuntimeException("订单状态不允许取消");
        }
        
        order.setStatus(LaundryOrder.OrderStatus.CANCELLED);
        order.setCancelReason(reason);
        
        // 创建进度记录
        OrderProgress progress = new OrderProgress();
        progress.setOrder(order);
        progress.setStatus(LaundryOrder.OrderStatus.CANCELLED);
        progress.setDescription("订单已取消：" + reason);
        progress.setOperator("用户");
        orderProgressRepository.save(progress);
        
        return orderRepository.save(order);
    }
    
    @Transactional
    public LaundryOrder rateOrder(Long id, Integer rating, String review, String images) {
        LaundryOrder order = getOrderById(id);

        if (order.getStatus() != LaundryOrder.OrderStatus.DELIVERED) {
            throw new RuntimeException("只有已送达的订单才能评价");
        }

        if (order.getRating() != null) {
            throw new RuntimeException("订单已经评价过了");
        }

        order.setRating(rating);
        order.setReview(review);
        order.setReviewTime(LocalDateTime.now());

        return orderRepository.save(order);
    }

    public List<OrderProgress> getOrderProgress(Long id) {
        LaundryOrder order = getOrderById(id);
        return orderProgressRepository.findByOrderOrderByCreatedAtAsc(order);
    }

    @Transactional
    public LaundryOrder reorder(Long id) {
        LaundryOrder originalOrder = getOrderById(id);

        // 创建新订单
        LaundryOrder newOrder = new LaundryOrder();
        newOrder.setUser(originalOrder.getUser());
        newOrder.setCustomerName(originalOrder.getCustomerName());
        newOrder.setCustomerPhone(originalOrder.getCustomerPhone());
        newOrder.setPickupAddress(originalOrder.getPickupAddress());
        newOrder.setDeliveryAddress(originalOrder.getDeliveryAddress());
        newOrder.setTotalAmount(originalOrder.getTotalAmount());
        newOrder.setFinalAmount(originalOrder.getFinalAmount());
        newOrder.setNotes("重新下单 - 原订单号: " + originalOrder.getOrderNumber());
        newOrder.setStatus(LaundryOrder.OrderStatus.PENDING);
        newOrder.setPaymentStatus(LaundryOrder.PaymentStatus.UNPAID);

        LaundryOrder savedOrder = orderRepository.save(newOrder);

        // 复制订单项
        List<OrderItem> originalItems = orderItemRepository.findByOrder(originalOrder);
        List<OrderItem> newItems = new ArrayList<>();

        for (OrderItem originalItem : originalItems) {
            OrderItem newItem = new OrderItem();
            newItem.setOrder(savedOrder);
            newItem.setService(originalItem.getService());
            newItem.setServiceName(originalItem.getServiceName());
            newItem.setUnitPrice(originalItem.getUnitPrice());
            newItem.setQuantity(originalItem.getQuantity());
            newItem.setTotalPrice(originalItem.getTotalPrice());
            newItem.setNotes(originalItem.getNotes());
            newItems.add(newItem);
        }

        orderItemRepository.saveAll(newItems);

        // 创建订单进度记录
        OrderProgress progress = new OrderProgress();
        progress.setOrder(savedOrder);
        progress.setStatus(LaundryOrder.OrderStatus.PENDING);
        progress.setDescription("重新下单，等待确认");
        progress.setOperator("用户");
        orderProgressRepository.save(progress);

        return savedOrder;
    }

    private String getStatusDescription(LaundryOrder.OrderStatus status) {
        switch (status) {
            case PENDING:
                return "订单待确认";
            case CONFIRMED:
                return "订单已确认";
            case PICKED_UP:
                return "已取件";
            case PROCESSING:
                return "处理中";
            case COMPLETED:
                return "已完成";
            case DELIVERED:
                return "已送达";
            case CANCELLED:
                return "订单已取消";
            case REFUNDED:
                return "已退款";
            default:
                return "未知状态";
        }
    }
    
    public Map<String, Object> getOrderStats() {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userRepository.findByUsernameOrEmailOrMobile(username, username, username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        Map<String, Object> stats = new java.util.HashMap<>();
        
        // 统计各状态订单数量
        stats.put("total", orderRepository.countByUser(user));
        stats.put("pending", orderRepository.countByUserAndStatus(user, LaundryOrder.OrderStatus.PENDING));
        stats.put("confirmed", orderRepository.countByUserAndStatus(user, LaundryOrder.OrderStatus.CONFIRMED));
        stats.put("processing", orderRepository.countByUserAndStatus(user, LaundryOrder.OrderStatus.PROCESSING));
        stats.put("completed", orderRepository.countByUserAndStatus(user, LaundryOrder.OrderStatus.COMPLETED));
        stats.put("delivered", orderRepository.countByUserAndStatus(user, LaundryOrder.OrderStatus.DELIVERED));
        stats.put("cancelled", orderRepository.countByUserAndStatus(user, LaundryOrder.OrderStatus.CANCELLED));
        
        return stats;
    }
}
